package com.njh.charges.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hos.entity.his.*;
import com.hos.entity.sys.User;
import com.hos.utils.IdGeneratorUtil;
import com.hos.utils.WebUtil;
import com.njh.charges.config.AlipayConfig;
import com.njh.charges.feigns.UserFeign;
import com.njh.charges.mapper.*;
import com.njh.charges.service.BackFeeService;
import com.njh.charges.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author ：njh
 * @date ：Created in 2023/12/15 16:45
 * @description：
 * @modified By：
 * @version:
 */
@Service
public class BackFeeImplService implements BackFeeService {

    @Resource
    private OrderChargeMapper orderChargeMapper;
    @Resource
    private OrderChargeItemMapper orderChargeItemMapper;
    @Resource
    private OrderBackFeeMapper orderBackFeeMapper;
    @Resource
    private OrderBackFeeItemMapper orderBackFeeItemMapper;
    @Resource
    private CareHistoryMapper careHistoryMapper;
    @Resource
    private CareOrderVoMapper careOrderVoMapper;
    @Resource
    private CareOrderItemMapper careOrderItemMapper;
    @Resource
    private UserFeign userFeign;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private AlipayConfig alipayConfig;

    @Override
    public Page<OrderBackfee> queryAllOrderBackfeeForPage(AllOrderBackFeeVo allOrderBackFeeVo) {
        // 设置分页参数
        Page<OrderBackfee> page = new Page<>(allOrderBackFeeVo.getPageNum(), allOrderBackFeeVo.getPageSize());

        LambdaQueryWrapper<OrderBackfee> wrapper = new LambdaQueryWrapper<>();
        // 进行条件查询
        if (StringUtils.hasText(allOrderBackFeeVo.getPatientName())) {
            page.setCurrent(1);
            wrapper.like(OrderBackfee::getPatientName, allOrderBackFeeVo.getPatientName());
        }
        if (StringUtils.hasText(allOrderBackFeeVo.getRegId())) {
            page.setCurrent(1);
            wrapper.eq(OrderBackfee::getRegId, allOrderBackFeeVo.getRegId());
        }

        return this.orderBackFeeMapper.selectPage(page, wrapper);
    }

    @Override
    public List<OrderBackfeeItem> queryOrderBackfeeItemByBackId(String backId) {

        LambdaQueryWrapper<OrderBackfeeItem> wrapper = new LambdaQueryWrapper<>();
        // 进行条件查询
        if (StringUtils.hasText(backId)) {
            wrapper.eq(OrderBackfeeItem::getBackId, backId);
        }

        return this.orderBackFeeItemMapper.selectList(wrapper);
    }

    @Override
    public Map getChargedCareHistoryByRegId(String regId) {

        //查病历表
        LambdaQueryWrapper<CareHistory> wrapper = new LambdaQueryWrapper<>();
        // 进行条件查询
        if (StringUtils.hasText(regId)) {
            wrapper.eq(CareHistory::getRegId, regId);
        }
        CareHistory careHistory = this.careHistoryMapper.selectOne(wrapper);


        //根据ch_id查处方表获取co_id
        LambdaQueryWrapper<CareOrderVo> wrapper2 = new LambdaQueryWrapper<>();
        // 进行条件查询
        if (StringUtils.hasText(careHistory.getChId())) {
            wrapper2.eq(CareOrderVo::getChId, careHistory.getChId());
        }
        List<CareOrderVo> careOrders = this.careOrderVoMapper.selectList(wrapper2);

        List l = new ArrayList();

        for (int i = 0; i < careOrders.size(); i++) {
            //根据co_id查处方详情表
            LambdaQueryWrapper<CareOrderItem> wrapper3 = new LambdaQueryWrapper<>();
            // 进行条件查询
            if (StringUtils.hasText(careOrders.get(i).getCoId())) {
                wrapper3.eq(CareOrderItem::getCoId, careOrders.get(i).getCoId());
            }
            wrapper3.eq(CareOrderItem::getStatus, 1);
            List<CareOrderItem> careOrderItems = this.careOrderItemMapper.selectList(wrapper3);
            if (careOrderItems.isEmpty()) {
                l.add(i);
                continue;
            }
            careOrders.get(i).setCareOrderItems(careOrderItems);
        }

        //删除无需发药的careOrders列表
        for (int i = 0; i <l.size(); i++) {
            careOrders.remove(Integer.parseInt(String.valueOf(l.get(i))));
        }


        Map map = new HashMap();
        map.put("careHistory", careHistory);
        map.put("careOrders", careOrders);

        return map;
    }

    @Override
    public Boolean createOrderBackfeeWithCash(OrderBackfeeVo orderBackfeeVo) {

        //根据item_id修改his_care_order_item的status
        //新建his_order_backfee（订单）    ch_id,reg_id不变  自创back_id
        //新建his_order_backfee_item(订单详情)     co_id直接拿    back_id如上    自创item_id（每个都不一样）


        String backId = IdGeneratorUtil.nextId("ODB");
        Double sum = 0D;

        for (OrderBackfeeItem c :
                orderBackfeeVo.getOrderBackfeeItemDtoList()) {

            sum += c.getItemAmount().doubleValue();

            UpdateWrapper<CareOrderItem> wrapper = new UpdateWrapper();
            wrapper.lambda()
                    .set(CareOrderItem::getStatus, 2)
                    .eq(CareOrderItem::getItemId, c.getItemId());
            careOrderItemMapper.update(wrapper);


            //新建his_order_backfee_item(退费详情)     co_id直接拿    back_id如上    自创item_id（每个都不一样）
            OrderBackfeeItem orderBackfeeItem = new OrderBackfeeItem();
            orderBackfeeItem.setItemId(c.getItemId());
            orderBackfeeItem.setCoId(c.getCoId());
            orderBackfeeItem.setItemName(c.getItemName());
            orderBackfeeItem.setItemPrice(c.getItemPrice());
            orderBackfeeItem.setItemNum(c.getItemNum().intValue());
            orderBackfeeItem.setItemAmount(c.getItemAmount().intValue());
            orderBackfeeItem.setBackId(backId);
            orderBackfeeItem.setItemType(c.getItemType());
            orderBackfeeItem.setStatus("2");
            orderBackFeeItemMapper.insert(orderBackfeeItem);

        }

        //新建his_order_backfee（订单）    ch_id,reg_id不变  自创back_id
        OrderBackfee orderBackfee = new OrderBackfee();
        orderBackfee.setBackId(backId);
        orderBackfee.setBackAmount(BigDecimal.valueOf(sum));
        orderBackfee.setChId(orderBackfeeVo.getOrderBackfeeDto().getChId());
        orderBackfee.setRegId(orderBackfeeVo.getOrderBackfeeDto().getRegId());
        orderBackfee.setPatientName(orderBackfeeVo.getOrderBackfeeDto().getPatientName());
        orderBackfee.setBackStatus("1");
        orderBackfee.setBackType("0");
        orderBackfee.setOrderId(null);
        orderBackfee.setBackPlatformId(null);
        orderBackfee.setBackTime(new Date());
        orderBackfee.setCreateTime(new Date());
        orderBackfee.setUpdateTime(null);
        orderBackfee.setCreateBy(getUserByToken().getUserName());
        orderBackfee.setUpdateBy(null);
        orderBackFeeMapper.insert(orderBackfee);

        return null;
    }

    @Override
    public String createOrderBackfeeWithZfb(OrderBackfeeVo orderBackfeeVo) throws AlipayApiException {
        //保存提交请求后返回的提示
        List msgList=new ArrayList();

        // 1. 创建Client，通用SDK提供的Client，负责调用支付宝的API
        String format = "json";
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.getGatewayUrl(), alipayConfig.getAppId(),
                alipayConfig.getPrivateKey(), format, alipayConfig.getCharset(), alipayConfig.getPublicKey(), alipayConfig.getSignType());

        //遍历orderBackfeeVo的OrderBackfeeItem得到itemids
        //根据itemid查orderid
        //根据不同的orderid退款各自的item订单
        //setOutTradeNo = 不同的orderid
        //setOutRequestNo = backId(如上)
        //退款成功后修改数据库---
        //根据item_id修改his_care_order_item的status
        //新建his_order_backfee（订单）    ch_id,reg_id不变  自创back_id
        //新建his_order_backfee_item(订单详情)     co_id直接拿    back_id如上
        Set orderIdSet = new HashSet();
        List itemIdList = new ArrayList();
        for (OrderBackfeeItem o :
                orderBackfeeVo.getOrderBackfeeItemDtoList()) {
            //根据itemid查orderid
            QueryWrapper<OrderChargeItem> wrapper = new QueryWrapper();
            wrapper.lambda()
                    .eq(OrderChargeItem::getItemId, o.getItemId());
            List<OrderChargeItem> orderChargeItems = orderChargeItemMapper.selectList(wrapper);
            for (OrderChargeItem orderChargeItem :
                    orderChargeItems) {
                orderIdSet.add(orderChargeItem.getOrderId());
            }
            itemIdList.add(o.getItemId());
        }
        //去重后得到数组
        List<String> orderIds= new ArrayList<>(orderIdSet);
        //去除掉非支付宝支付的订单号
        QueryWrapper<OrderCharge> wrapper6 = new QueryWrapper();
        wrapper6.lambda()
                .eq(OrderCharge::getPayType, "1")
                .and(i1->i1.in(OrderCharge::getOrderId,orderIds));
        List<OrderCharge> orderCharges = orderChargeMapper.selectList(wrapper6);
        List<String> orderIdList= new ArrayList<>();
        for (OrderCharge orderCharge :
                orderCharges) {
            orderIdList.add(orderCharge.getOrderId());
        }




        //根据不同的orderid退款各自的item订单
        for (int i = 0; i < orderIdList.size(); i++) {

            String backId = IdGeneratorUtil.nextId("ODB");
            Double sum = 0D;

            QueryWrapper<OrderChargeItem> wrapper2 = new QueryWrapper<>();
            wrapper2.lambda()
                    .eq(OrderChargeItem::getOrderId, orderIdList.get(i))
                    .and(i2 -> i2.in(OrderChargeItem::getItemId, itemIdList));
//                    .in(OrderChargeItem::getItemId, itemIdList)
            List<OrderChargeItem> orderChargeItems = orderChargeItemMapper.selectList(wrapper2);

            for (OrderChargeItem o :
                    orderChargeItems) {
                sum += o.getItemAmount().doubleValue();
            }
            System.out.println(sum);

            //setOutTradeNo = 不同的orderid
            //setOutRequestNo = backId(如上)
            //请求对象,调用支付宝 不同接口，需使用不同对象
            AlipayTradeRefundRequest alipayTradeCloseRequest = new AlipayTradeRefundRequest();
            //请求参数集合对象,除了公共参数之外,所有参数都可通过此对象传递
            AlipayTradeRefundModel alipayTradeRefundModel = new AlipayTradeRefundModel();
            //退款的订单号,传入生成支付订单时的订单号即可
            alipayTradeRefundModel.setOutTradeNo(String.valueOf(orderIdList.get(i)));
            //退款金额
            alipayTradeRefundModel.setRefundAmount(String.valueOf(sum));
            // 表示支持部分退款
            alipayTradeRefundModel.setOutRequestNo(backId);
//        //退款的原因
//        alipayTradeRefundModel.setRefundReason("haha");
            alipayTradeCloseRequest.setBizModel(alipayTradeRefundModel);
            AlipayTradeRefundResponse refundResponse = null;
            try {
                refundResponse = alipayClient.execute(alipayTradeCloseRequest);
            } catch (AlipayApiException e) {
                System.out.println(e);
            }
            msgList.add(refundResponse.getSubMsg());
            if (refundResponse.getFundChange() != null) {
                //退款的执行流程与支付不太一样,支付时成功之后，需要通知回调接口,而退款则不需要,只需判断响应参数 refundResponse.getFundChange().equals("Y") 判断是否发生了资金变化, equals("Y")表示资金发生了变化，退款成功
                if (refundResponse.getFundChange().equals("Y")) {

                    //退款成功后修改数据库---
                    //根据item_id修改his_care_order_item的status
                    //新建his_order_backfee（订单）    ch_id,reg_id不变  自创back_id
                    //新建his_order_backfee_item(订单详情)     co_id直接拿    back_id如上
                    if(orderChargeItems!=null){
                        for (OrderChargeItem c :
                                orderChargeItems) {

                            //修改careorderitem状态  Status 2已退费
                            UpdateWrapper<CareOrderItem> wrapper = new UpdateWrapper();
                            wrapper.lambda()
                                    .set(CareOrderItem::getStatus, 2)
                                    .eq(CareOrderItem::getItemId, c.getItemId());
                            careOrderItemMapper.update(wrapper);


                            //新建his_order_backfee_item(退费详情)     co_id直接拿    back_id如上    自创item_id（每个都不一样）
                            OrderBackfeeItem orderBackfeeItem = new OrderBackfeeItem();
                            orderBackfeeItem.setItemId(c.getItemId());
                            orderBackfeeItem.setCoId(c.getCoId());
                            orderBackfeeItem.setItemName(c.getItemName());
                            orderBackfeeItem.setItemPrice(c.getItemPrice());
                            orderBackfeeItem.setItemNum(c.getItemNum().intValue());
                            orderBackfeeItem.setItemAmount(c.getItemAmount().intValue());
                            orderBackfeeItem.setBackId(backId);
                            orderBackfeeItem.setItemType(c.getItemType());
                            orderBackfeeItem.setStatus("2");
                            orderBackFeeItemMapper.insert(orderBackfeeItem);

                        }

                        //新建his_order_backfee（订单）    ch_id,reg_id不变  自创back_id
                        OrderBackfee orderBackfee = new OrderBackfee();
                        orderBackfee.setBackId(backId);
                        orderBackfee.setBackAmount(BigDecimal.valueOf(sum));
                        orderBackfee.setChId(orderBackfeeVo.getOrderBackfeeDto().getChId());
                        orderBackfee.setRegId(orderBackfeeVo.getOrderBackfeeDto().getRegId());
                        orderBackfee.setPatientName(orderBackfeeVo.getOrderBackfeeDto().getPatientName());
                        orderBackfee.setBackStatus("1");
                        orderBackfee.setBackType("1");
                        orderBackfee.setOrderId(String.valueOf(orderIdList.get(i)));

                        String tradeNo = refundResponse.getTradeNo();
                        if(StringUtils.hasText(tradeNo)){
                            orderBackfee.setBackPlatformId(tradeNo);
                        }else{
                            orderBackfee.setBackPlatformId(null);
                        }

                        orderBackfee.setBackTime(new Date());
                        orderBackfee.setCreateTime(new Date());
                        orderBackfee.setUpdateTime(null);
                        orderBackfee.setCreateBy(getUserByToken().getUserName());
                        orderBackfee.setUpdateBy(null);
                        orderBackFeeMapper.insert(orderBackfee);

                    }


                }
            }

        }


        return String.valueOf(msgList);
    }


    /**
     * @return com.hos.entity.sys.User
     * @create by: 陈海彬
     * @description: 获取请求用户的信息
     * @create time: 2023/12/12 10:39
     */
    private User getUserByToken() {
        String token = WebUtil.getToken();
        String phone = redisTemplate.opsForValue().get("user:" + token);
        return userFeign.selectUserByPhone(phone);
    }


}